#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "flvio.h"
#include "scan.h"
#include "err.h"

static void help(void)
{
	printf("Split flv stream into tags or gops.\n\n"
	"Usage: %s [-g] [FILE [PREFIX]]\n", progname);
}

const char *prefix;

static int uint_width(unsigned u)
{
	int w;
	for (w = 1; u /= 10; w++);
	return w;
}
static void rename_extra_zeros(char *oldpath, unsigned offset,
			unsigned from, unsigned to)
{
	unsigned i;
	int width;
	char *newpath;
	newpath = (char *)malloc(offset + 100);
	if (!newpath)
		die(1);
	memcpy(newpath, oldpath, offset);
	width = uint_width(to);
	for (i = from; i <= to; i++) {
		sprintf(oldpath + offset, "%u", i);
		sprintf(newpath + offset, "%0*u", width, i);
		if (strcmp(oldpath + offset, newpath + offset) == 0)
			continue;
		if (rename(oldpath, newpath) < 0)
			diemsg(1, path);
	}
	free(newpath);
}

static scan_verdict
callback(scan_phase phase, struct tagbuf *b, struct context *ctx)
{
	static FILE *out;
	char *suffix;
	unsigned from, to;

	suffix = path + prefix_len;
	switch (phase) {
	case BEFORE:
	case HDR:
		strcpy(suffix, "hdr");
		out = open_file(path, 'w');
		if (!out || write_tag(out, b) < 0)
			return ERROR;
		close_file(out);
		out = 0;
		break;

	case TAG:
		if (!target_gop) {
			sprintf(suffix, "tag%u", ctx->tag[0].ord);
			out = open_file(path, 'w');
			if (!out || write_tag(out, b) < 0)
				return ERROR;
			close_file(out);
			out = 0;
		} else if (ctx->gop[0].first.ord == ctx->gop[0].last.ord) {
			sprintf(suffix, "gop%u", ctx->gop[0].ord);
		 	if (out)
				close_file(out);
			out = open_file(path, 'w');
			if (!out || write_tag(out, b) < 0)
				return ERROR;
		}

		break;

	case AFTER:
		if (ctx->tag[0].ord == 0 || ctx->gop[0].last.ord == 0)
			break;
		if (out)
			close_file(out);
		if (!target_gop) {
			from = 1;
			to = ctx->tag[0].ord;
			strcpy(suffix, "tag");
		} else {
			from = 1;
			to = ctx->gop[0].ord;
			if (to == 0)
				from = 0;
			strcpy(suffix, "gop");
		}
		rename_extra_zeros(path, prefix_len + 3, from, to);
		break;

	default:
		break;
	}

	return DISCARD;
}

int split_main(int argc, char **argv)
{
	int r;
	char **args;
	const char *file;
	FILE *in;

	if (getopts(argc, argv, 0, 1) < 0) {
		help();
		return 2;
	}
	if (show_help) {
		help();
		return 0;
	}

	args = getnargs(argc, argv, 2);
	file = args[0];
	prefix = args[1];
	if (!prefix)
		prefix = file;

	in = open_file(file, 'r');
	r = scan(in, 0, callback);
	close_file(in);

	free(args);
	return r;
}
